package nckd.wnqjt.tmc.tda.plugin.form;

import java.sql.Timestamp;
import java.util.*;

import com.alibaba.fastjson.JSON;
import kd.bos.ai.util.JsonUtil;
import kd.bos.algo.DataSet;
import kd.bos.algo.Row;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.entity.AppInfo;
import kd.bos.entity.AppMetadataCache;
import kd.bos.entity.qing.*;
import kd.bos.entity.report.ReportQueryParam;
import kd.bos.form.IFormView;
import kd.bos.form.IPageCache;
import kd.bos.form.ShowType;
import kd.bos.form.control.IQingAnalysis;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.list.ListShowParameter;
import kd.bos.mvc.SessionManager;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.report.ReportShowParameter;
import kd.bos.servicehelper.QueryServiceHelper;

/**
 * @author husheng
 * @date 2024-11-04 11:55
 * @description 动态表单插件      应收票据
 */
public class ReceivablebillQingDataProvider extends AbstractFormPlugin implements IQingDataProvider {
    /**
     * 定义轻分析表头
     */
    @Override
    public QingMeta getMeta(String s) {
        String entityKey = "cdm_receivablebill";
        QingMeta meta = new QingMeta();
        EntryEntity entity = new EntryEntity();
        entity.setKey(entityKey);
        entity.setName(new LocaleString("PK"));
        entity.setPkFieldName("id");
        meta.addEntryEntity(entity);

        Field column = new Field();
        column.setEntity(entityKey);//字段所属实体key	否
        column.setKey("id");// 字段名(唯一标识)	是
        column.setFieldType(QingFieldType.Int.toNumber()); //数据类型	是
        column.setName(new LocaleString("id")); //字段别名	是
        meta.addColumn(column);

        column = new Field();
        column.setEntity(entityKey);
        column.setKey("companyName");
        column.setFieldType(QingFieldType.String.toNumber());
        column.setName(new LocaleString("资金组织"));
        meta.addColumn(column);

        column = new Field();
        column.setEntity(entityKey);
        column.setKey("bizdate");
        column.setFieldType(QingFieldType.Date.toNumber());
        column.setName(new LocaleString("日期"));
        meta.addColumn(column);

        column = new Field();
        column.setEntity(entityKey);
        column.setKey("type");
        column.setFieldType(QingFieldType.String.toNumber());
        column.setName(new LocaleString("类型"));
        meta.addColumn(column);

        column = new Field();
        column.setEntity(entityKey);
        column.setKey("amount");
        column.setFieldType(QingFieldType.Number.toNumber());
        column.setName(new LocaleString("总额"));
        meta.addColumn(column);

        return meta;
    }

    /**
     * 获取轻分析数据，通过拿到过滤条件可以重新定义取数逻辑
     */
    @Override
    public QingData getData(String s, int i, int i1) {
        //拿过滤条件，进行取数
        String qFilter = getPageCache().get("qFilter");
        if (qFilter != null) {
            //通过此方法拿到过滤参数
            Map<String, Object> filterParam = (Map) JSON.parseObject(qFilter, Map.class);
        }

        Date currentDate = this.getCurrentDate();

        /**
         * 票据类型
         * 102	电子银行承兑汇票
         * 104	电子商业承兑汇票
         * 105	支票
         * 106	银行本票
         * CDMT-79A2C33B	云票
         *
         * 票据状态
         * 已登记	registered
         * 已质押	pledged
         * 已托管	collocated
         * 已背书	endorsed
         * 已贴现	discounted
         * 已托收	collected
         */
        // 收票登记
        String receivablebillSql = "id,company.id companyId,company.name companyName,company.number companyNumber,bizdate,draftbilltype.number draftbilltypeNumber,amount,draftbillstatus";
        QFilter filter = new QFilter("rptype", QCP.equals, "receivebill")
                .and("draftbilltype.number", QCP.in, new String[]{"102", "104", "CDMT-79A2C33B"})
                .and("billstatus", QCP.equals, "C")
                .and("bizdate", QCP.less_equals, currentDate)
                .and("draftbillexpiredate", QCP.large_equals, currentDate)
                .and("draftbillstatus", QCP.in, new String[]{"registered", "endorsed", "pledged", "collocated", "discounted", "collected"})
                .and("draftbilltranstatus", QCP.equals, "success");
        DataSet cdmReceivablebill = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cdm_receivablebill", receivablebillSql, filter.toArray(), null);

        // 根据票据状态分开取值
        DataSet cdmReceivablebill1 = cdmReceivablebill.copy().filter("draftbillstatus = 'registered'");
        DataSet cdmReceivablebill2 = cdmReceivablebill.copy().filter("draftbillstatus in ('endorsed','pledged','discounted','collected')");
        DataSet cdmReceivablebill3 = cdmReceivablebill.copy().filter("draftbillstatus = 'collocated'");

        // 业务处理
        String drafttradebillSql = "id,entrys.draftbill,bizdate drbizdate";

        /*
            已登记的票据有两种，一种是未做任何业务处理的，另一种是做过质押解除
            如果登记状态的票据有解除质押的，需保留解除质押的，业务日期小于等于查询日期
         */
        QFilter filter1 = new QFilter("tradetype", QCP.equals, "rlspledge");
        DataSet cdmDrafttradebill1 = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cdm_drafttradebill", drafttradebillSql, filter1.toArray(), null);

        DataSet finish1 = cdmReceivablebill1.leftJoin(cdmDrafttradebill1).on("id", "entrys.draftbill").select(cdmReceivablebill2.getRowMeta().getFieldNames(), new String[]{"drbizdate"}).finish();

        DataSet drafttradebill1 = finish1.copy().filter("drbizdate is null");
        DataSet drafttradebill2 = finish1.copy().filter("drbizdate is not null and drbizdate <= to_date('" + currentDate + "','yyyy-MM-dd hh:mm:ss')");
        DataSet finish2 = drafttradebill1.select(cdmReceivablebill.getRowMeta().getFieldNames());
        DataSet finish3 = drafttradebill2.select(cdmReceivablebill.getRowMeta().getFieldNames());


        // 业务日期大于查询日期
        QFilter filter2 = new QFilter("bizdate", QCP.large_than, currentDate)
                .and("tradetype", QCP.in, new String[]{"endorse", "pledge", "discount", "collect"});
        DataSet cdmDrafttradebill2 = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cdm_drafttradebill", drafttradebillSql, filter2.toArray(), null);

        DataSet finish4 = cdmReceivablebill2.join(cdmDrafttradebill2).on("id", "entrys.draftbill").select(cdmReceivablebill2.getRowMeta().getFieldNames()).finish();

        // 合并结果集
        DataSet receivablebill = cdmReceivablebill3.union(finish2, finish3, finish4);

        // 根据票据类型分类
        DataSet receivablebill1 = receivablebill.copy().filter("draftbilltypeNumber = '102'");
        DataSet receivablebill2 = receivablebill.copy().filter("draftbilltypeNumber = '104'");
        DataSet receivablebill3 = receivablebill.copy().filter("draftbilltypeNumber = 'CDMT-79A2C33B'");

        DataSet dataSet1 = receivablebill1.select(new String[]{"id", "companyName", "bizdate", "amount", "'银行承兑' as type"});
        DataSet dataSet2 = receivablebill2.select(new String[]{"id", "companyName", "bizdate", "amount", "'商业承兑' as type"});
        DataSet dataSet3 = receivablebill3.select(new String[]{"id", "companyName", "bizdate", "amount", "'类票据' as type"});

        DataSet dataSet = dataSet1.union(dataSet2, dataSet3);

        QingData data = null;
        if (i < 200) {
            data = new QingData();
            Map<String, Integer> dataindex = new HashMap<>();
            dataindex.put("id", 0);
            dataindex.put("companyName", 1);
            dataindex.put("bizdate", 2);
            dataindex.put("type", 3);
            dataindex.put("amount", 4);
            data.setDataindex(dataindex);

            List<Object[]> rows = new ArrayList<>();
            while (dataSet.hasNext()) {
                Row row = dataSet.next();
                Object[] obj = new Object[5];
                obj[0] = row.getLong("id");
                obj[1] = row.getString("companyName");
                Timestamp timestamp = (Timestamp) row.get("bizdate");
                long time = timestamp.getTime();
                obj[2] = time;
                obj[3] = row.getString("type");
                obj[4] = row.getBigDecimal("amount");
                rows.add(obj);
            }
            data.setRows(rows);
        }

        return data;
    }

    /**
     * 获取动态表单联查信息
     *
     * @param pageId
     * @param ctrKey
     * @return
     */
    @Override
    public List<QingLinkageInfo> getLinkageInfo(String pageId, String ctrKey) {
        List<QingLinkageInfo> infos = new ArrayList<QingLinkageInfo>();
        QingLinkageInfo info = new QingLinkageInfo();
        Map<String, String> formKey = new HashMap<>();
        AppInfo appInfo = AppMetadataCache.getAppInfo("tda");
        formKey.put("AppId", appInfo.getAppId()); //需要打开的表单所在应用的id
        formKey.put("FormId", "nckd_receivablebillreport"); //需要打开的表单的id
        formKey.put("System", "IERP");
        formKey.put("CtrKey", ctrKey);
        info.setFormKey(JsonUtil.encodeToString(formKey));
        info.setFormDisplayName("应收票据");//联查到表单的显示名称
        info.setFormPrimaryKey("id");//联查到表单的主键
        infos.add(info);//可以添加多个QingLinkageInfo对象
        this.getView().getPageCache().put("qingViewControlKey", ctrKey);//必要语句!
        return infos;
    }

    /**
     * <p>调用此接口，触发业务逻辑，具体业务联查实现此接口<p/>
     *
     * @param ids    轻分析得到动态表单需要联査的1d的集合
     * @param pageId
     * @param formId
     * @param appId
     */
    @Override
    public void fireLinkageInfo(List<String> ids, String pageId, String formId, String appId) {
        //IQingDataProvider.super.fireLinkageInfo(ids, pageId, formId, appId);
        /*具体的表单打开逻辑，业务自己去实现
        ids:联查到的主键的值
        pageId:触发联査的页面的pageId，可用于找到触发联査的页面: FormView view = (FormView)Sessiomanager.getCurrent().getView(pageId)
        formId:联查到的表单的id
        appId:联查到的表单所在应用的Id
        */

        /*注意: 如果需要使用芒穹的view.showForm 方式打开表单，需要添加以下代码*/
        // 组装 FormShomParaneter(披照业务场景亲实现)
        ReportShowParameter reportShowParameter = new ReportShowParameter();
        reportShowParameter.getOpenStyle().setShowType(ShowType.Modal);
        reportShowParameter.setAppId(appId);
        reportShowParameter.setFormId(formId);//报表标识
        //拿过滤条件，进行取数
        String qFilter = getPageCache().get("qFilter"); //从仪表板进去 拿不到
        //通过此方法拿到过滤参数
        Map<String, Object> filterParam = new HashMap<>();
        // 设置报表过滤条件
        ReportQueryParam reportQueryParam = new ReportQueryParam();
        filterParam.put("id", ids);
        reportQueryParam.setCustomParam(filterParam);
        reportShowParameter.setQueryParam(reportQueryParam);

        /*******************************showForm必要的代码******************************************/
        IFormView view = SessionManager.getCurrent().getView(pageId);
        String ctrKey = this.getView().getPageCache().get("qingViewControlKey");
        if (ctrKey != null) {
            if (view.getControl(ctrKey) instanceof IQingAnalysis) {
                //设计器的场景，直接showForm
                view.showForm(reportShowParameter);
                return;
            }
        }
        //其他场景需要，返回FormShowParameter，由轻分析来 showForm
        this.getView().setClientReturnData(ListShowParameter.toJsonString(reportShowParameter));
        /*******************************showForm必要的代码******************************************/
    }

    @Override
    public void setFilterParameter(String filterParameter) {
        IPageCache pageCache = getPageCache();
        pageCache.put("qFilter", filterParameter);

    }

    @Override
    public String getFilterParameter() {
        return getPageCache().get("qFilter");
    }

    private Date getCurrentDate() {
        Calendar cal = new GregorianCalendar();
//        cal.set(11, 0);
//        cal.set(12, 0);
//        cal.set(13, 0);
//        cal.set(14, 0);
        return cal.getTime();
    }
}
